package com.yonyou.pmclouds.picture.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.billstatus.BillStatusConst;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertMultiProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoUpdateProcessor;
import com.yonyou.pmclouds.basecom.bp.template.MultiInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleDeleteBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleUpdateBpTemplate;
import com.yonyou.pmclouds.basecom.entity.SuperVO;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.basecom.util.CommonFieldConst;
import com.yonyou.pmclouds.businessobject.util.BulkDataSplitUtils;
import com.yonyou.pmclouds.picture.entity.PictureParamVO;
import com.yonyou.pmclouds.picture.entity.PictureToNCCVO;
import com.yonyou.pmclouds.picture.entity.PictureVO;
import com.yonyou.pmclouds.picture.mapper.PictureMapper;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = PictureRemoteService.class)
public class PictureRemoteServiceImpl implements PictureRemoteService {

    @Autowired
    private PictureMapper pictureMapper;

    @Override
    public PictureVO[] insertPictures(PictureVO[] pictureVOs) throws BusinessException {

        MultiInsertBpTemplate<PictureVO> bp = new MultiInsertBpTemplate<PictureVO>(pictureMapper);
        //补全图片的创建者，以及创建时间
        bp.addBeforeProcessor(new AuditInfoInsertMultiProcessor<PictureVO>());
        //进行图片的批量添加
        bp.insert(pictureVOs);
        return pictureVOs;
    }

    @Override
    public String[] queryPicNamesByPkEntity(String pk_entity) {

        PictureVO[] picVOs = pictureMapper.queryPicByPkEntity(pk_entity);
        String[] picNames = new String[picVOs.length];
        for (int i = 0; i < picNames.length; i++) {
            picNames[i] = picVOs[i].getPicture_name();
        }

        return picNames;
    }

    @Override
    public Map<String, List<String>> queryPicsByPkEntitys(String[] pk_entitys) throws BusinessException {

        PictureVO[] pictureVOS = queryByPkEntities(pk_entitys);

        if (ArrayUtils.isEmpty(pictureVOS)) {
            return new HashMap<>();
        }
        HashMap<String, List<String>> map = new HashMap<>(pictureVOS.length);

        for (PictureVO pictureVO : pictureVOS) {
            //获取图片对应的检查项主键
            String key = pictureVO.getPk_entity();
            List<String> list = map.get(key);
            if (list == null || list.size() == 0) {
                list = new ArrayList<>();
            }
            list.add(pictureVO.getPicture_name());
            //集合中对应的是每个检查项主键对应的所有的图片地址的集合
            map.put(key, list);
        }
        return map;
    }

    private PictureVO[] queryByPkEntities(String[] pkEntities){
        if (pkEntities == null || pkEntities.length == 0) {
            return null;
        }

        Set<String> pkEntitiesSet = new HashSet<>();
        Collections.addAll(pkEntitiesSet, pkEntities);

        //利用检查项ID获取所对应的所有图片
        return pictureMapper.queryByLargePkEntities(BulkDataSplitUtils.getSplitDataSet(pkEntitiesSet));
    }

    @Override
    public Map<String, List<PictureVO>> queryByLargePkEntities(String[] pk_entitys) throws BusinessException {
        PictureVO[] pictureVOS = queryByPkEntities(pk_entitys);

        if (ArrayUtils.isEmpty(pictureVOS)) {
            return new HashMap<>();
        }

        Map<String, List<PictureVO>> pictureMap = new HashMap<>();
        for(PictureVO pictureVO : pictureVOS){
            List<PictureVO> pictureVOList = pictureMap.get(pictureVO.getPk_entity());
            if(pictureVOList == null){
                pictureVOList = new ArrayList<>();
                pictureVOList.add(pictureVO);
                pictureMap.put(pictureVO.getPk_entity(), pictureVOList);
            }else{
                pictureVOList.add(pictureVO);
            }

        }
        return pictureMap;
    }

    @Override
    public PictureVO[] insertPictureForPub(SuperVO busiVO, PictureParamVO paramVO) throws BusinessException {

        //获取传入对象中pictures数组
        String[] picNames = (String[]) BeanHelper.getProperty(busiVO, CommonFieldConst.PICTURES);
        //若没有图片则返回
        if (picNames == null || picNames.length == 0) {
            return null;
        }
        //创建一个存图片对象的集合
        List<PictureVO> picList = new ArrayList<>();

        for (int i = 0; i < picNames.length; i++) {
            PictureVO picVO = new PictureVO();
            picVO.setPicture_name(picNames[i]);
            //存入检查项主键  这个就是得到主键的方法
            picVO.setPk_entity((String) busiVO.pkFiledValue());
            //补全picVO对象中单据主键、项目主键、以及单据类型等字段信息
            fillBusiInfoForPicture(picVO, busiVO, paramVO);
            //添加单据状态为6，驳回后再提交状态   ？？？？？？？？？？？不明白
            picVO.setBill_status(BillStatusConst.COMMON_COMMIT_STATUS);
            //图片排序字段
            picVO.setSequence(i + 1);
            //将图片对象添加进集合中
            picList.add(picVO);
        }
        //集合转数组去添加图片
        return this.insertPictures(picList.toArray(new PictureVO[0]));

    }

    @Override
    public PictureVO[] insertPicturesForPub(SuperVO[] busiVOs, PictureParamVO paramVO) throws BusinessException {

        if (busiVOs == null || busiVOs.length == 0)
            return null;

        List<PictureVO> picList = new ArrayList<PictureVO>();

        for (SuperVO busiVO : busiVOs) {

            String[] picNames = (String[]) BeanHelper.getProperty(busiVO, CommonFieldConst.PICTURES);

            if (picNames == null || picNames.length == 0)
                continue;


            for (int i = 0; i < picNames.length; i++) {
                PictureVO picVO = new PictureVO();
                picVO.setPicture_name(picNames[i]);
                picVO.setPk_entity((String) busiVO.pkFiledValue());

                fillBusiInfoForPicture(picVO, busiVO, paramVO);
                picVO.setBill_status(BillStatusConst.COMMON_COMMIT_STATUS);
                picVO.setSequence(i + 1);

                picList.add(picVO);
            }

        }
        PictureVO[] pics = null;
        if (picList != null && picList.size() > 0) {
            pics = insertPictures(picList.toArray(new PictureVO[]{}));
        }
        return pics;


    }

    /**
     * 方法功能描述：填充图片表中的业务信息。
     *
     * <b>参数说明</b>
     *
     * @param picVO
     * @param busiVO
     * @param paramVO
     * @author zhangwce
     * @time 2017年11月27日 上午11:11:40
     */
    private void fillBusiInfoForPicture(PictureVO picVO, SuperVO busiVO, PictureParamVO paramVO) {
        if (paramVO != null && paramVO.getPk_bill() != null) {
            picVO.setPk_bill(paramVO.getPk_bill());
        } else {
            picVO.setPk_bill((String) busiVO.pkFiledValue());
        }
        if (paramVO != null && paramVO.getPk_project() != null) {
            picVO.setPk_project(paramVO.getPk_project());
        } else {
            picVO.setPk_project(BeanHelper.getProperty(busiVO, CommonFieldConst.PK_PROJECT) == null ? "~"
                    : (String) BeanHelper.getProperty(busiVO, CommonFieldConst.PK_PROJECT));
        }
        if (paramVO != null && paramVO.getSrc_bill_type() != null) {
            picVO.setSrc_bill_type(paramVO.getSrc_bill_type());
        } else {
            picVO.setSrc_bill_type((String) BeanHelper.getProperty(busiVO,CommonFieldConst.BILL_TYPE));
        }
    }

    @Override
    public PictureVO[] insertBodyPictureForPub(SuperVO[] bodyVOs, PictureParamVO paramVO) throws BusinessException {

        Map<String, String[]> bodyPicMap = new HashMap<String, String[]>();
        Map<String, SuperVO> pkBodyVOMap = new HashMap<String, SuperVO>();

        String[] tempPictureVOs = null;
        for (SuperVO bodyVO : bodyVOs) {
            tempPictureVOs = (String[]) BeanHelper.getProperty(bodyVO, CommonFieldConst.PICTURES);
            if (tempPictureVOs == null || tempPictureVOs.length == 0)
                continue;
            bodyPicMap.put(BeanHelper.getId(bodyVO), tempPictureVOs);
            pkBodyVOMap.put(BeanHelper.getId(bodyVO), bodyVO);
        }

        List<PictureVO> insertPicList = new ArrayList<PictureVO>();

        String[] bodyPictures = null;
        for (String pk_body : bodyPicMap.keySet()) {
            bodyPictures = bodyPicMap.get(pk_body);
            for (int i = 0; i < bodyPictures.length; i++) {
                PictureVO picVO = new PictureVO();
                picVO.setPicture_name(bodyPictures[i]);
                picVO.setPk_entity(pk_body);

                fillBusiInfoForPicture(picVO, pkBodyVOMap.get(pk_body), paramVO);

                picVO.setSequence(i + 1);
                insertPicList.add(picVO);
            }
        }

        if (insertPicList == null || insertPicList.size() == 0)
            return null;

        return this.insertPictures(insertPicList.toArray(new PictureVO[0]));
    }

    @Override
    public PictureVO[] deletePictures(String pk_entity, String[] picNames) throws BusinessException {

        PictureVO[] pictureVOs = pictureMapper.queryByPkEntityAndPicNames(pk_entity, picNames);

        if (pictureVOs == null || pictureVOs.length == 0)
            return null;

        SingleDeleteBpTemplate<PictureVO> bp = new SingleDeleteBpTemplate<PictureVO>(pictureMapper);

        PictureVO[] delPictures = new PictureVO[pictureVOs.length];

        for (int i = 0; i < pictureVOs.length; i++) {
            delPictures[i] = bp.delete(pictureVOs[i]);
        }

        return delPictures;
    }

    @Override
    public PictureVO[] updateBillPicture(SuperVO busiVO, PictureParamVO paramVO) throws BusinessException {
        PictureVO[] oldPictures = pictureMapper.queryPicByPkEntity(busiVO.pkFiledValue() == null ? null : (String) busiVO.pkFiledValue());
        //创建一个删除单个实体模板对象
        SingleDeleteBpTemplate<PictureVO> bp = new SingleDeleteBpTemplate<PictureVO>(pictureMapper);
        //逐个删除图片对象，即把对象的dr属性值置为1
        if (oldPictures != null && oldPictures.length != 0) {
            for (int i = 0; i < oldPictures.length; i++) {
                bp.delete(oldPictures[i]);
            }
        }
        //再插入新的图片对象
        return insertPictureForPub(busiVO, paramVO);
    }

    @Override
    public void updatePicBillStatusByBill(String pkBill, byte status) {
        pictureMapper.updateStatusByPkBill(pkBill, status);
    }

    @Override
    public Map<String, List<PictureVO>> getPicsByPkBill(String[] pkBills) throws BusinessException {
        if (pkBills == null || pkBills.length == 0) {
            return new HashMap<>();
        }
        // 结果集
        Map<String, List<PictureVO>> pkPicsMap = new HashMap<>();
        PictureVO[] pictureVOS = pictureMapper.queryByPkBills(pkBills);
        for (String pkBill : pkBills) {
            for (PictureVO pictureVO : pictureVOS) {
                if (pkBill.equals(pictureVO.getPk_bill())) {
                    if (pkPicsMap.get(pkBill) == null) {
                        List<PictureVO> picList = new ArrayList<>();
                        picList.add(pictureVO);
                        pkPicsMap.put(pictureVO.getPk_bill(), picList);
                    } else {
                        pkPicsMap.get(pkBill).add(pictureVO);
                    }
                }
            }
        }
        return pkPicsMap;
    }

    @Override
    public PictureVO[] updateExamplePics(PictureVO[] pictureVOS, String pkBill) throws BusinessException {
        if (StringUtils.isEmpty(pkBill))
            return new PictureVO[0];
        PictureVO[] originPics = pictureMapper.queryExamplesByBill(pkBill);
        // 新增、更新和删除的集合
        List<PictureVO> insertVos = new ArrayList<>();
        List<PictureVO> updateVos = new ArrayList<>();
        List<PictureVO> deleteVos = new ArrayList<>();
        getOperateList(insertVos, updateVos, deleteVos, originPics, pictureVOS);
        // 数据库操作
        if (insertVos.size() > 0)
            this.insertPictures(insertVos.toArray(new PictureVO[insertVos.size()]));
        if (updateVos.size() > 0) {
            SingleUpdateBpTemplate<PictureVO> updateBpTemplate = new SingleUpdateBpTemplate<>(pictureMapper, new String[]{PictureVO.TITLE, PictureVO.DESCRIPTION});
            updateBpTemplate.addBeforeProcessor(new AuditInfoUpdateProcessor<PictureVO>());
            for (PictureVO vo : updateVos) {
                updateBpTemplate.update(vo);
            }
        }
        if (deleteVos.size() > 0) {
            SingleDeleteBpTemplate<PictureVO> deleteBpTemplate = new SingleDeleteBpTemplate<>(pictureMapper);
            deleteBpTemplate.addBeforeProcessor(new AuditInfoUpdateProcessor<PictureVO>());
            for (PictureVO vo : deleteVos) {
                deleteBpTemplate.delete(vo);
            }
        }

        return pictureVOS;
    }

    /**
     * 获得本次操作要新增、更新和删除的数据
     *
     * @param insertVos
     * @param updateVos
     * @param deleteVos
     * @param originPics
     * @param pictureVOS
     */
    private void getOperateList(List<PictureVO> insertVos, List<PictureVO> updateVos, List<PictureVO> deleteVos, PictureVO[] originPics, PictureVO[] pictureVOS) {
        Map<String, PictureVO> pkToPic = new HashMap<>();
        if (ArrayUtils.isNotEmpty(originPics)) {
            for (PictureVO pictureVO : originPics) {
                pkToPic.put(pictureVO.getPk_picture(), pictureVO);
            }
        }
        // 得到新增、更新的数据集合
        Set<String> pkSet = new HashSet<>();
        String pk;
        if (ArrayUtils.isNotEmpty(pictureVOS)) {
            for (PictureVO vo : pictureVOS) {
                pk = vo.getPk_picture();
                if (StringUtils.isEmpty(pk)) {
                    insertVos.add(vo);
                } else if (pkToPic.containsKey(pk)) {
                    PictureVO oldPic = pkToPic.get(pk);
                    if (!oldPic.getTitle().equals(vo.getTitle()) || !oldPic.getDescription().equals(vo.getDescription()))
                        updateVos.add(vo);
                    pkSet.add(pk);
                }
            }
        }
        // 得到要删除的数据集合
        if (pkToPic.size() > 0) {
            for (String pkPic : pkToPic.keySet()) {
                if (!pkSet.contains(pkPic))
                    deleteVos.add(pkToPic.get(pkPic));
            }
        }
    }

    @Override
    public PictureVO[] queryExamplePicsByEntity(String pkEntity) throws BusinessException {
        if (StringUtils.isEmpty(pkEntity))
            return new PictureVO[0];

        return pictureMapper.queryExamplePicsByEntity(pkEntity);
    }

    @Override
    public PictureVO[] deleteExamplePicsOfBill(String pkBill) throws BusinessException {
        if (StringUtils.isEmpty(pkBill))
            return new PictureVO[0];

        PictureVO[] delPics = pictureMapper.queryExamplesByBill(pkBill);
        if (ArrayUtils.isEmpty(delPics))
            return new PictureVO[0];

        return this.deleteExamplePics(delPics);
    }

    @Override
    public PictureVO[] deleteExamplePicsOfEntity(String pkEntity) throws BusinessException {
        if (StringUtils.isEmpty(pkEntity))
            return new PictureVO[0];

        PictureVO[] delPics = pictureMapper.queryExamplePicsByEntity(pkEntity);
        if (ArrayUtils.isEmpty(delPics))
            return new PictureVO[0];

        return this.deleteExamplePics(delPics);
    }

    /**
     * 删除示例照片
     *
     * @param delPics
     * @return
     */
    private PictureVO[] deleteExamplePics(PictureVO[] delPics) throws BusinessException {
        if (ArrayUtils.isEmpty(delPics))
            return new PictureVO[0];

        PictureVO[] deletedPics = new PictureVO[delPics.length];
        SingleDeleteBpTemplate<PictureVO> bp = new SingleDeleteBpTemplate<>(pictureMapper);
        bp.addBeforeProcessor(new AuditInfoUpdateProcessor<PictureVO>());
        // 删除
        for (int i = 0; i < delPics.length; i++) {
            deletedPics[i] = bp.delete(delPics[i]);
        }

        return deletedPics;
    }

    @Override
    public List<PictureToNCCVO> queryByPksTONCC(Map<String, String[]> typePksMap) throws BusinessException {
        List<String> pkBillList = new ArrayList<>();
        if(typePksMap == null){
            return new ArrayList<>();
        }

        for(Map.Entry<String, String[]> entry : typePksMap.entrySet()){
            pkBillList.addAll(Arrays.asList(entry.getValue()));
        }

        if(pkBillList.size() <= 0){
            return new ArrayList<>();
        }

        PictureVO[] pictureVOS = pictureMapper.queryByPkBills(pkBillList.toArray(new String[]{}));
        if(pictureVOS == null || pictureVOS.length <= 0){
            return new ArrayList<>();
        }

        Map<String, List<String>> pictureVOMap = new HashMap<>();
        for(PictureVO pictureVO : pictureVOS){
            List<String> pictureUrlList = pictureVOMap.get(pictureVO.getPk_bill());
            if(pictureUrlList == null){
                pictureUrlList = new ArrayList<>();
                pictureVOMap.put(pictureVO.getPk_bill(), pictureUrlList);
            }
            pictureUrlList.add(pictureVO.getPicture_name());
        }

        List<PictureToNCCVO> pictureToNCCVOS = new ArrayList<>();
        for(Map.Entry<String, String[]> entry : typePksMap.entrySet()){
            String billType = entry.getKey();
            for(String pkBill : entry.getValue()){
                PictureToNCCVO pictureToNCCVO = new PictureToNCCVO();
                pictureToNCCVO.setBilltype(billType);
                pictureToNCCVO.setPkBill(pkBill);
                List<String> pictureUrlList = pictureVOMap.get(pkBill);
                if(pictureUrlList != null && pictureUrlList.size() > 0){
                    pictureToNCCVO.setUrls(pictureUrlList.toArray(new String[]{}));
                }
                pictureToNCCVOS.add(pictureToNCCVO);
            }
        }

        return pictureToNCCVOS;
    }
}
